package com.orm_plus;

import com.spring.bean.BeanDefinition;
import com.spring.context.BeanDefinitionRegistry;
import com.spring.enums.ScopeType;
import com.spring.beanpostprocessor.BeanDefinitionRegistryPostProcessor;
import com.spring.util.ClassUtils;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;


@Slf4j
public class MapperScannerConfig implements BeanDefinitionRegistryPostProcessor {
	private DataSource dataSource;
	private String basePackage;
	
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	
	public void setBasePackage(String basePackage) {
		this.basePackage = basePackage;
	}
	
	
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		
		List<BeanDefinition> beanDefinitions = doScan(basePackage);
		for (BeanDefinition bd : beanDefinitions) {
			registry.registryBeanDefinition(bd.getBeanName(), bd);
		}
		
	}
	
	public static List<BeanDefinition> doScan(String scanPath) {
		List<BeanDefinition> bds = new ArrayList<>(16);
		
		try {
			Enumeration<URL> resources = MapperScannerConfig.class.getClassLoader().getResources(scanPath.replace(".", "/"));      // 从类加载类拿到url路径
			while (resources.hasMoreElements()) {
				URL url = resources.nextElement();
				String decodePath = URLDecoder.decode(url.getPath(), "utf-8");    // URL路径如果含有中文 ，需要解码才能使用
				File rootFile = new File(decodePath);
				
				if (!rootFile.exists()) {
					continue;
				}
				
				File[] files = rootFile.listFiles();
				for (File file : files) {
					if (file.isDirectory()) {
						bds.addAll(doScan(scanPath + "." + file.getName()));   // 递归调用下一层级扫描
					} else {
						if (file.isFile() && file.getName().endsWith(".class")) {
							String classSimpleName = getClassSimpleName(file);
							String fullClassName = scanPath + "." + classSimpleName;
							Class<?> clazz = loadClass(fullClassName);
							
							// 只给接口代理
							if (clazz.isInterface()) {
								
								BeanDefinition bd = new BeanDefinition();
								bd.setBeanName(classSimpleName.substring(0, 1).toLowerCase() + classSimpleName.substring(1));
								bd.setScope(ScopeType.SINGLE);
								bd.setBeanClass(clazz);           // 直接写入 接口的类型
								
								// bd.setFactoryBeanName("com.my.MapperFactoryBean");   // ?? 固定写死？
								bd.setFactoryBeanName(MapperFactoryBean.class.getName());   // 不要写死
								
								bd.setConstructorArgumentValues(new Class[]{clazz});    // 接口类型丢进去
								
								bds.add(bd);
								
								// log.info("添加了接口 {} 的定义信息",clazz.getName());
							}
						}
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bds;
	}
	
	
	public static String getClassSimpleName(File f) {
		return f.getName().replace(".class", "");
	}
	
	
	public static ClassLoader getClassLoader() {
		return MapperScannerConfig.class.getClassLoader();
	}
	
	public static Class<?> loadClass(String className) {
		try {
			Class<?> clazz = ClassUtils.class.getClassLoader().loadClass(className);
			return clazz;
		} catch (ClassNotFoundException e) {
			System.out.println(className + " 类找不到,无法加载");
		}
		return null;
	}
}
